﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Collections.ObjectModel;

namespace E4D.AppFabric.Entities.Engine
{
    class Session : ISession
    {
        private Runspace runspace;

        public Session(Runspace runspace)
        {
            this.runspace = runspace;
        }

        public Session(Runspace runspace, ICollection<string> modules)
        {
            this.runspace = runspace;

            foreach (var name in modules)
            {
                InvokeInternal(runspace, "Import-Module", new Dictionary<String, object>{{"Name", name}});
            }
        }

        public virtual void Dispose()
        {
            if (runspace != null)
            {
                runspace.Dispose();
                runspace = null;
            }
        }

        private static Collection<PSObject> InvokeInternal(Runspace runspace, string commandName, IDictionary<string, object> parameters)
        {
            var isScript = commandName.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Length > 1 &&
                           parameters.Count == 0;

            var cmd = new Command(commandName, isScript);

            foreach (var c in parameters)
            {
                cmd.Parameters.Add(new CommandParameter(c.Key, c.Value));
            }

            using (Pipeline pipeLine = runspace.CreatePipeline())
            {
                pipeLine.Commands.Add(cmd);
                return pipeLine.Invoke();
            }
        }

        private static Collection<PSObject> InvokeInternal(Runspace runspace, string commandName)
        {
            using (Pipeline pipeLine = runspace.CreatePipeline())
            {
                pipeLine.Commands.Add(commandName);
                return pipeLine.Invoke();
            }
        }

        public void UseCacheHost()
        {
            InvokeInternal(runspace, "Import-Module");
        }

        public void UseCacheCluster(String provider, String connectionString)
        {
            var p = new Dictionary<string, object>();

            if (!string.IsNullOrEmpty(connectionString))
            {
                p.Add("ConnectionString", connectionString);
                p.Add("Provider", provider);
            }

            InvokeInternal(runspace, "Use-CacheCluster", p);
        }

        public Collection<PSObject> Invoke(string commandName, IDictionary<string, object> parameters)
        {
            return InvokeInternal(runspace, commandName, parameters);
        }

        public Collection<PSObject> Invoke(string commandName)
        {
            return InvokeInternal(runspace, commandName);
        }

    }
}
